Skip to main content

Slice

  • Concept
    • slice 為 reference type

      https://i.imgur.com/52NveLB.png

    • array 長度固定,slice 長度不固定

    • slice 其實是 struct,底層是 array,以下是 source code

      // runtime/slice.go
      type slice struct {
      array unsafe.Pointer
      len int
      cap int
      }
  • 二維 Slice 宣告寫法
    • 要分兩段宣告

      package main

      import (
      "fmt"
      )

      func main() {
      // 宣告方法 (2*3)
      // 也可以這樣宣告,但這樣會是 array -> result := [2][3]int{}
      result := make([][]int, 2)
      for i := range result {
      result[i] = make([]int, 3)
      }

      result[0][1] = 0
      result[0][1] = 2
      result[0][2] = 5
      result[1][0] = 0
      result[1][1] = 4
      result[1][2] = 6

      fmt.Println(result) // [[0 2 5] [0 4 6]]
      }
  • Example
    • make 寫法 make(<type>, <len>, <cap>),cap 可以不寫,default 會與 len 一樣

    • 取出 slice 區間的方式 input[low:high] (low 為初始 index,且要比 high 的 index 小)

      package main

      import "fmt"

      func main() {
      s := make([]string, 4)
      fmt.Println(s) // [ ]

      s[0] = "1"
      s[1] = "2"
      s[2] = "8"
      s[3] = "10"

      fmt.Println(s) // [1 2 8 10]

      fmt.Println("length:", len(s)) // length: 4

      // 幾種不同用法
      fmt.Println(s[1:3]) // index: 1~2 -> [2 8]
      fmt.Println(s[1:]) // index: 1~end -> [2 8 10]
      fmt.Println(s[:2]) // index: 0~1 -> [1 2]
      }
    • append 第二個參數為 ...Type 如果用 slice 作為參數傳入,則要寫成 slice... (對 slice 做一個 unpack 的動作)

      package main

      import (
      "fmt"
      )

      func main() {

      names := []string{"dane", "ks"}
      fmt.Println("len:", len(names))
      fmt.Println("cap:", cap(names))

      newNames := []string{"4545", "454545"}

      names = append(names, newNames...) // slice...
      fmt.Println("len:", len(names))
      fmt.Println("cap:", cap(names))

      fmt.Println(names)
      }
  • 注意事項 底層 array 可以被多個 slice 同時指向,因此對一個 slice 操作有可能連帶影響到其他 slice
    package main

    import "fmt"

    func main() {
    slice := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
    s1 := slice[2:5]
    s2 := s1[2:6:7]

    s2 = append(s2, 100)
    s2 = append(s2, 200)

    s1[2] = 20

    fmt.Println(s1)
    fmt.Println(s2)
    fmt.Println(slice)
    }

Reference

数组与切片有什么异同